import kotlinx.browser.document
import kotlinx.browser.window
import org.khronos.webgl.Float32Array
import org.khronos.webgl.set
import org.w3c.dom.HTMLElement
import three.*
import kotlin.random.Random

fun main() {
    window.onload = {
        val scene = Scene()
        val camera = PerspectiveCamera(75.0, window.innerWidth.toDouble() / window.innerHeight, 0.1, 1000.0)
        val renderer = WebGLRenderer()
        renderer.setSize(window.innerWidth, window.innerHeight)
        document.body?.appendChild(renderer.domElement as HTMLElement)

        val particles = 1000000
        val geometry = BufferGeometry()
        val positions = Float32Array(particles * 3)
        val velocities = Array(particles) { Vector3() }

        for (i in 0 until particles) {
            positions[i * 3] = Random.nextFloat() * 2 - 1
            positions[i * 3 + 1] = Random.nextFloat() * 2 - 1
            positions[i * 3 + 2] = Random.nextFloat() * 2 - 1

            velocities[i] = Vector3(
                (Random.nextFloat() - 0.5f) * 0.02f,
                (Random.nextFloat() - 0.5f) * 0.02f,
                (Random.nextFloat() - 0.5f) * 0.02f
            )
        }

        geometry.setAttribute("position", BufferAttribute(positions, 3))

        val material = PointsMaterial().apply {
            color.setHex(0xffff00)
            size = 0.03
        }

        val points = Points(geometry, material)
        scene.add(points)

        camera.position.z = 5.0f

        fun animate() {
            window.requestAnimationFrame { animate() }

            val positionsAttr = points.geometry.attributes["position"] as BufferAttribute

            for (i in 0 until particles) {
                val x = positionsAttr.getX(i) + velocities[i].x
                val y = positionsAttr.getY(i) + velocities[i].y
                val z = positionsAttr.getZ(i) + velocities[i].z

                positionsAttr.setXYZ(i, x, y, z)
            }

            positionsAttr.needsUpdate = true

            renderer.render(scene, camera)
        }

        animate()
    }
}
